/* 
 * File:   Monster.cpp
 * Author: Potential
 * 
 * Created on September 14, 2013, 6:19 PM
 */

#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <ctime>
#include "Monster.h"

Monster::Monster() {
    name = "";
    curHealth = 100;
    maxHealth = 100;
    minDamage = 10;
    maxDamage = 20;
    armor = 5;
    
    level = 0;
    experience = 0;
    maxExperience = 10;

    criticalStrikeChance = 10;
    criticalStrikeMultiplier = 1.5;

    srand(static_cast<unsigned int> (time(0))); // seed random number
}

Monster::~Monster() {

}

void Monster::setName(string name) {
    this->name = name;
}

void Monster::setCurHealth(int curHealth) {
    this->curHealth = curHealth;
}

void Monster::setMaxHealth(int maxHealth) {
    this->maxHealth = maxHealth;
}

void Monster::setMinDamage(int minDamage) {
    this->minDamage = minDamage;
}

void Monster::setMaxDamage(int maxDamage) {
    this->maxDamage = maxDamage;
}

void Monster::setArmor(int armor) {
    this->armor = armor;
}

void Monster::resetHealth() {
    curHealth = maxHealth;
}

void Monster::monsterSelection(int monsterNum) {
    if (monsterNum == 1) {
        name = "Dragon";
    } else if (monsterNum == 2) {
        name = "Phoenix";
    } else if (monsterNum == 3) {
        name = "Leviathan";
    } else if (monsterNum == 4) {
        name = "Golem";
    } else if (monsterNum == 5) {
        name = "Pegasus";
    } else if (monsterNum == 6) {
        name = "Cerberus";
    }//Should never go here, but just in case
    else {
        name = "Dragon";
    }
}

void Monster::setMaxExperience(int maxExperience) {
    this->maxExperience = maxExperience;
}

int Monster::getMaxExperience() const {
    return maxExperience;
}

void Monster::setExperience(int experience) {
    this->experience = experience;
}

int Monster::getExperience() const {
    return experience;
}

void Monster::gainExperience(int exp) {
    experience = experience + exp;
    while (experience >= maxExperience) {
        experience = experience - maxExperience;
        levelUp();
    }
}

void Monster::setLevel(int level) {
    this->level = level;
}

int Monster::getLevel() const {
    return level;
}

void Monster::levelUp() {
    level++;
    increaseStats();
}

void Monster::increaseStats() {
    maxHealth = maxHealth + 7 + (1 + rand() % 5);
    minDamage = minDamage + 6 + (1 + rand() % 3 );
    maxDamage = maxDamage + 9 + (1 + rand() % 3 );
    armor = armor + 8 + (1 + rand() % 3 );
    maxExperience = maxExperience + 10*level;
}

int Monster::getDamage() {
    int damage = 0;
    damage = (rand() % (maxDamage - minDamage)) + minDamage;

    if (isCriticalStrike() == true) {
        damage = damage * getCriticalStrikeMultiplier();
    }

    return damage;
}

void Monster::displayStats() {
    cout << "===========================" << endl;
    cout << "Monster: " << name << endl;
    cout << "Level: " << level << endl;
    cout << "Health: " << curHealth << " / " << maxHealth << endl;
    cout << "Damage: " << minDamage << " - " << maxDamage << endl;
    cout << "Armor: " << armor << endl;
    cout << "Experience: " << experience << " / " << maxExperience << endl;
    cout << "===========================" << endl << endl;
}

void Monster::setCriticalStrikeMultiplier(double criticalStrikeMultiplier) {
    this->criticalStrikeMultiplier = criticalStrikeMultiplier;
}

double Monster::getCriticalStrikeMultiplier() const {
    return criticalStrikeMultiplier;
}

void Monster::setCriticalStrikeChance(int criticalStrikeChance) {
    this->criticalStrikeChance = criticalStrikeChance;
}

int Monster::getCriticalStrikeChance() const {
    return criticalStrikeChance;
}

void Monster::setCriticalStrike() {
    int critSeed = rand() % 100 + 1;

    if (getCriticalStrikeChance() >= critSeed) {
        criticalStrike = true;
    } else {
        criticalStrike = false;
    }
}

bool Monster::isCriticalStrike() const {
    return criticalStrike;
}